home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / lib / bar_plot.pro < prev    next >
Encoding:
Text File  |  1997-07-08  |  10.5 KB  |  249 lines

  1. ; $Id: bar_plot.pro,v 1.4 1997/01/15 03:11:50 ali Exp $
  2. ;
  3. ; Copyright (c) 1990-1997, Research Systems, Inc.  All rights reserved.
  4. ;    Unauthorized reproduction prohibited.
  5. ;
  6.  
  7. pro bar_plot,values,baselines=baselines,colors=colors,barnames=barnames, $
  8.           title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $
  9.           barwidth=barwidth,barspace=barspace,baroffset=baroffset, $
  10.           outline=outline,overplot=overplot,background=background, $
  11.           rotate=rotate
  12. ;+
  13. ; NAME:  
  14. ;    BAR_PLOT
  15. ;
  16. ; PURPOSE:
  17. ;    Create a bar graph, or overplot on an existing one.
  18. ;
  19. ; CATEGORY:
  20. ;    Graphics.
  21. ;
  22. ; CALLING SEQUENCE:
  23. ;    BAR_PLOT, Values
  24. ;
  25. ; INPUTS:
  26. ;    Values:    A vector containing the values to be represented by the bars.
  27. ;        Each element in VALUES corresponds to a single bar in the
  28. ;        output.
  29. ;
  30. ; KEYWORD PARAMETERS:
  31. ;   BASELINES:    A vector, the same size as VALUES, that contains the
  32. ;        base value associated with each bar.  If not specified,
  33. ;        a base value of zero is used for all bars.
  34. ;
  35. ;      COLORS:    A vector, the same size as VALUES, containing the color index
  36. ;        to be used for each bar.  If not specified, the colors are
  37. ;        selected based on spacing the color indices as widely as 
  38. ;        possible within the available colors (specified by D.N_COLORS).
  39. ;
  40. ;    BARNAMES:    A string array, containing one string label per bar.
  41. ;        If the bars are vertical, the labels are placed beneath
  42. ;        them.  If horizontal (rotated) bars are specified, the labels
  43. ;        are placed to the left of the bars.
  44. ;
  45. ;    TITLE:    A string containing the main title to for the bar plot.
  46. ;
  47. ;    XTITLE:    A string containing the title for the X axis.
  48. ;
  49. ;    YTITLE:    A string containing the title for the Y axis.
  50. ;
  51. ;   BASERANGE:    A floating-point scalar in the range 0.0 to 1.0, that
  52. ;        determines the fraction of the total available plotting area
  53. ;        (in the direction perpendicular to the bars) to be used.
  54. ;        If not specified, the full available area is used.
  55. ;
  56. ;    BARWIDTH:    A floating-point value that specifies the width of the bars
  57. ;        in units of "nominal bar width".  The nominal bar width is
  58. ;        computed so that all the bars (and the space between them, 
  59. ;        set by default to 20% of the width of the bars) will fill the 
  60. ;        available space (optionally controlled with the BASERANGE 
  61. ;        keyword).
  62. ;
  63. ;    BARSPACE:     A scalar that specifies, in units of "nominal bar width",
  64. ;        the spacing between bars.  For example, if BARSPACE is 1.0,
  65. ;        then all bars will have one bar-width of space between them.
  66. ;        If not specified, the bars are spaced apart by 20% of the bar
  67. ;        width.
  68. ;
  69. ;   BAROFFSET:    A scalar that specifies the offset to be applied to the
  70. ;        first bar, in units of "nominal bar width".  This keyword 
  71. ;        allows, for example, different groups of bars to be overplotted
  72. ;        on the same graph.  If not specified, the default offset is
  73. ;        equal to BARSPACE.
  74. ;
  75. ;     OUTLINE:    If set, this keyword specifies that an outline should be 
  76. ;        drawn around each bar.
  77. ;
  78. ;    OVERPLOT:    If set, this keyword specifies that the bar plot should be
  79. ;        overplotted on an existing graph.
  80. ;
  81. ;  BACKGROUND:    A scalar that specifies the color index to be used for
  82. ;        the background color.  By default, the normal IDL background
  83. ;        color is used.
  84. ;
  85. ;    ROTATE:    If set, this keyword indicates that horizontal rather than
  86. ;        vertical bars should be drawn.  The bases of horizontal bars
  87. ;        are on the left, "Y" axis and the bars extend to the right.
  88. ;
  89. ; OUTPUTS:
  90. ;    A bar plot is created, or an existing one is overplotted.
  91. ;
  92. ; EXAMPLE:
  93. ;    By using the overplotting capability, it is relatively easy to create
  94. ;    stacked bar charts, or different groups of bars on the same graph.
  95. ;
  96. ;    For example, if ARRAY is a two-dimensional array of 5 columns and 8
  97. ;    rows, it is natural to make a plot with 5 bars, each of which is a
  98. ;    "stacked" composite of 8 sections.  First, create a 2D COLORS array,
  99. ;    equal in size to ARRAY, that has identical color index values across
  100. ;    each row to ensure that the same item is represented by the same color
  101. ;    in all bars.
  102. ;
  103. ;    With ARRAYS and COLORS defined, the following code fragment
  104. ;    illustrates the creation of stacked bars (note that the number of rows
  105. ;    and columns is arbitrary):
  106. ;
  107. ;    !Y.RANGE = [0,ymax] ; Scale range to accommodate the total bar lengths.
  108. ;    BASE = INTARR(NROWS)
  109. ;    FOR I = 0, NROWS-1 DO BEGIN
  110. ;       BAR_PLOT, ARRAY(*,I), COLORS=COLORS(*,I), BASELINES=BASE, $
  111. ;                 BARWIDTH=0.75, BARSPACE=0.25, OVER=(I GT 0)
  112. ;       BASE = BASE + ARRAY(*,I)
  113. ;    ENDFOR
  114. ;
  115. ;    To plot each row of ARRAY as a clustered group of bars within the same
  116. ;    graph, use the BASERANGE keyword to restrict the available plotting
  117. ;    region for each set of bars.  The sample code fragment below
  118. ;    illustrates this method:
  119. ;
  120. ;    FOR I = 0, NROWS-1 DO $
  121. ;       BAR_PLOT, ARRAY(*,I), COLORS=COLORVECT, BARWIDTH=0.8,BARSPACE=0.2, $
  122. ;         BAROFFSET=I*((1.0+BARSPACE)*NCOLS), OVER=(I GT 0), BASERANGE=0.19
  123. ;
  124. ;    where NCOLS is the number of columns in ARRAY, and COLORVECT is a
  125. ;    vector containing the color indices to be used for each group of
  126. ;    bars.  (In this example, each group uses the same set of colors, but
  127. ;    this could easily be changed.)
  128. ;
  129. ; MODIFICATION HISTORY:
  130. ;    August 1990, T.J. Armitage, RSI, initial programming.  Replacement
  131. ;    for PLOTBAR and OPLOTBAR routines written by William Thompson.
  132. ;
  133. ;    September 1990, Steve Richards, RSI, changed defaults to improve the
  134. ;    appearance of the bar plots in the default mode. Included
  135. ;    spacing the bars slightly.
  136. ;-
  137. if (n_params(d) eq 0) then begin  ;Print call & return if no parameters
  138.   print,'bar_test,values,baselines=baselines,colors=colors,barnames=barnames,$'
  139.   print,' title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $'
  140.   print,' barwidth=barwidth,barspace=barspace,baroffset=baroffset, $'
  141.   print,' outline=outline,overplot=overplot,background=background, $'
  142.   print,' rotate=rotate'
  143.   return
  144. endif
  145.  
  146. nbars=n_elements(values)        ; Determine number of bars
  147. ; Baselines (bars extend from baselines through values); default=0
  148. if not(keyword_set(baselines)) then baselines=intarr(nbars)
  149. ; Default colors spaced evenly in current color table
  150. if not(keyword_set(colors)) then $
  151.    colors=fix((!d.n_colors/float(nbars))*(indgen(nbars)+0.5))
  152. ; Labels for the individual bars; none by default
  153. if not(keyword_set(barnames)) then barnames=strarr(nbars)+' '
  154. ; Main title
  155. if not(keyword_set(title)) then title=''
  156. ; Centered title under X-axis
  157. if not(keyword_set(xtitle)) then xtitle=''
  158. ; Title for Y-axis
  159. if not(keyword_set(ytitle)) then ytitle=''             
  160. ; Fraction (0-1) of full X range to use
  161. if not(keyword_set(baserange)) then baserange=1.0
  162. ; Space betw. bars, taken from nominal bar widths; default is none
  163. If not(keyword_set(barspace)) then barspace=0.2
  164. ; Bar width scaling factor, relative to nominal
  165. if not(keyword_set(barwidth)) then barwidth=1.0 - barspace - barspace / nbars
  166. ; Initial X offset, in scaled bar widths; default is none
  167. if not(keyword_set(baroffset)) then baroffset=barspace/barwidth
  168. ; Outline of bars; default is none
  169. outline = keyword_set(outline)
  170. ; Overplot (do not erase the existing display); default is to create new plot
  171. overplot = keyword_set(overplot)
  172. ; Background color index; defaults to 0 (usually black) if not specified
  173. if not(keyword_set(background)) then background=0
  174. ; Rotate (make horizontal bars); default is vertical bars
  175. rotate = keyword_set(rotate)
  176.  
  177. if (rotate) then begin                   ;Horizontal bars
  178.    if (!x.range[0] eq 0) and (!x.range[1] eq 0) $  ;Determine range for X-axis
  179.       then $
  180.         xrange=[(min(baselines)<min(values)), $    ;Minimum of bases & values
  181.                 (max(baselines)>max(values))] $    ;Maximum of bases & values
  182.       else xrange=!x.range               ;Or, use range specified
  183.    if (!y.range[0] eq 0) and (!y.range[1] eq 0) $  ;Plot will calculate  
  184.       then $                                       ; defaults for X, but not
  185.         yrange = [0, n_elements(values)] $         ; for Ys, so fill in here.
  186.       else $ 
  187.         yrange=!y.range                   ;Axis perpend. to bars
  188.    yticks=1                       ;Suppress ticks in plot
  189.    ytickname=strarr(2)+' '
  190.    xticks=0
  191.    xtickname=strarr(1)+''
  192. endif else begin                   ;Vertical bars
  193.    if (!y.range[0] eq 0) and (!y.range[1] eq 0) $  ;Determine range for Y-axis
  194.       then $
  195.         yrange=[(min(baselines)<min(values)), $    ;Minimum of bases & values
  196.                 (max(baselines)>max(values))] $    ;Maximum of bases & values
  197.       else yrange=!y.range                      ;Or, use range specified
  198.    xrange=!x.range                   ;Axis perpend. to bars
  199.    xticks=1                       ;Suppress ticks in plot
  200.    xtickname=strarr(2)+' '
  201.    yticks=0
  202.    ytickname=strarr(1)+''
  203. endelse
  204. if (overplot eq 0) then $               ;Create new plot, no data
  205. plot,[values],/nodata,title=title,xtitle=xtitle,ytitle=ytitle, $
  206.    noerase=overplot,xrange=xrange,yrange=yrange,xticks=xticks, $
  207.    xtickname=xtickname,yticks=yticks,ytickname=ytickname, $
  208.    xstyle=1,ystyle=1,/data,background=background
  209. if (rotate) then begin                   ;Horizontal bars
  210.    base_win=!y.window                   ;Window range in Y
  211.    scal_fact=!x.s                   ;Scaling factors
  212.    tick_scal_fact=!y.s                   ;Tick scaling factors
  213. endif else begin                   ;Vertical bars
  214.    base_win=!x.window                   ;Window range in X
  215.    scal_fact=!y.s                   ;Scaling factors
  216.    tick_scal_fact=!x.s                   ;Tick scaling factors
  217. endelse
  218. winrange=baserange*(base_win[1]-base_win[0])       ;Normal. window range
  219. barsize=barwidth*winrange/nbars               ;Normal. bar width
  220. winoffset=base_win[0]+(baroffset*barsize)       ;Normal. first offset
  221. bases=scal_fact[0]+(scal_fact[1]*baselines)       ;Baselines, in normal coor.
  222. normal=scal_fact[0]+(scal_fact[1]*values)       ;Values, in normal coor.
  223. barstart=indgen(nbars)*(barsize+barspace*(winrange/nbars)) ;Coor. at left edges
  224. tickv=winoffset+barstart+(0.5*barsize)           ;Tick coor. (centered)
  225. for i=0,nbars-1 do begin               ;Draw the bars
  226.    width=winoffset+[barstart[i],barstart[i], $     ;Compute bar width
  227.      (barstart[i]+barsize),(barstart[i]+barsize)]
  228.    length=[bases[i],normal[i],normal[i],bases[i]]  ;Compute bar length
  229.    if (rotate) then begin               ;Horizontal bars
  230.       x=length                       ;X-axis is "length" axis
  231.       y=width                       ;Y-axis is "width" axis
  232.    endif else begin                   ;Vertical bars
  233.       x=width                       ;X-axis is "width" axis
  234.       y=length                       ;Y-axis is "length" axis
  235.    endelse
  236.    polyfill,x,y,color=colors[i],/normal           ;Polyfill with color
  237.    if (outline) then plots,x,y,/normal           ;Outline using !p.color
  238. endfor
  239.  
  240. tickv=(tickv-tick_scal_fact[0])/tick_scal_fact[1]  ;Locations of the ticks
  241. if (rotate) then $                   ;Label the bars (Y-axis)
  242.   axis,yaxis=0,ystyle=1,yticks=(nbars-1),ytickv=tickv,ytickname=barnames, $
  243.   yticklen=0.0 $
  244. else $                           ;Label the bars (X-axis)
  245.   axis,xaxis=0,xstyle=1,xticks=(nbars-1),xtickv=tickv,xtickname=barnames, $
  246.   xticklen=0.0
  247. return
  248. end
  249.